package cloudspace.controlpanel.filemanager;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.springframework.security.core.context.SecurityContextHolder;

import cloudspace.config.CloudSpaceConfiguration;
import cloudspace.security.CloudSpaceUser;
import cloudspace.security.permissions.PermissionsManager;
import cloudspace.vm.filesystem.CSPath;
import cloudspace.vm.filesystem.ProjectSpec;


public class FileManagerModel
{
    protected static final String PATH_SEP = "/";

    protected CSPath currentDirectory;

    private static final Logger logger = Logger.getLogger( FileManagerModel.class );


    // ~ Constructors ..........................................................

    // ----------------------------------------------------------
    public FileManagerModel()
    {
        initStandardModel();
    }


    // ----------------------------------------------------------
    private void initStandardModel()
    {
        List<CSPath> roots = getRoots();

        if ( !roots.isEmpty() )
        {
            currentDirectory = roots.get( 0 );
        }
    }


    // ----------------------------------------------------------
    public List<CSPath> getRoots()
    {
        Object principal = SecurityContextHolder.getContext()
            .getAuthentication()
            .getPrincipal();

        if ( principal instanceof CloudSpaceUser )
        {
            return PermissionsManager.getInstance()
                .getUserRoots( (CloudSpaceUser)principal );
        }
        else if ( !CloudSpaceConfiguration.getInstance().isMultiUser() )
        {
            return PermissionsManager.getInstance().getAdminRoots();
        }
        else
        {
            return new ArrayList<CSPath>();
        }
    }


    // ----------------------------------------------------------
    public CSPath getCurrentDirectory()
    {
        return currentDirectory;
    }


    // ----------------------------------------------------------
    public void setCurrentDirectory( CSPath directory )
    {
        currentDirectory = directory;
    }


    // ----------------------------------------------------------
    public CSPath getPathForFile( String filename )
    {
        return new CSPath( currentDirectory, filename );
    }


    // ----------------------------------------------------------
    /**
     * Creates a new directory in the current directory with the specified name
     * and returns it.
     * 
     * @param name
     *            the name of the new directory
     * @return a CSPath representing the new directory
     */
    public CSPath createDirectory( String name )
    {
        CSPath newFolder = new CSPath( currentDirectory, name );
        newFolder.mkdir();
        return newFolder;
    }


    // ----------------------------------------------------------
    /**
     * Creates a new, empty file in the current directory with the specified
     * name and returns it.
     * 
     * @param name
     *            the name of the new file
     * @return a CSPath representing the new file
     */
    public CSPath createFile( String name ) throws IOException
    {
        CSPath newFile = new CSPath( currentDirectory, name );
        newFile.createNewFile();
        return newFile;
    }


    // ----------------------------------------------------------
    public CSPath renameFile( CSPath path, String newName )
    {
        CSPath newPath = new CSPath( path.getParent(), newName );
        path.moveTo( newPath );
        return newPath;
    }


    // ----------------------------------------------------------
    public void makeProject( CSPath path )
    {
        try
        {
            ProjectSpec.createProject( path );
        }
        catch ( IOException e )
        {
            logger.debug( "Could not create metadata for project" );

        }

    }


    // ----------------------------------------------------------
    public void fileCleanup( CSPath uploadedFile )
    {
        /*
         * String ext = getFileExtension(uploadedFile); try { Class<?>
         * cleanerClass = Class.forName("cloudspace.vm.filesystem.Intercept" +
         * ext.substring(1).toUpperCase()); UploadInterceptor cleaner =
         * (UploadInterceptor) cleanerClass.newInstance();
         * cleaner.cleanFile(uploadedFile); } catch (InstantiationException e) {
         * // TODO Auto-generated catch block e.printStackTrace(); } catch
         * (IllegalAccessException e) { // TODO Auto-generated catch block
         * e.printStackTrace(); } catch (ClassNotFoundException e) { // Do
         * nothing because there is no handler for this class. ; } catch
         * (Exception e) { // TODO: Pass the exception up a level }
         */

    }


    public void snapshotCurrentDirectory() throws IOException
    {
        Object principal = SecurityContextHolder.getContext()
            .getAuthentication()
            .getPrincipal();

        if ( principal instanceof CloudSpaceUser )
        {
            final SimpleDateFormat formatter = new SimpleDateFormat( "MMMddyyyy" );
            Date today = Calendar.getInstance().getTime();
            CSPath todayPath = new CSPath( "snapshot",
                ( (CloudSpaceUser)principal ).getUsername() + File.separator
                    + formatter.format( today ) );
            if ( !todayPath.exists() )
                todayPath.getPhysicalFile().mkdirs();
            String currentDirectoryName = getCurrentDirectory().getName();
            int submissions = todayPath.getChildren().size();
            String snapPath = "sub" + ( submissions )+"-"+currentDirectoryName;
            String finalPath = ( (CloudSpaceUser)principal ).getUsername()
                + File.separator + formatter.format( today ) + "/" + snapPath;
            CSPath path = new CSPath( "snapshot", finalPath );
            // CSPath path = new CSPath( "snapshot",( (CloudSpaceUser)principal
            // ).getUsername() );

            FileUtils.copyDirectoryToDirectory( this.getCurrentDirectory()
                .getPhysicalFile(), path.getPhysicalFile() );

        }

    }
}
